function varargout = TLTaskDlg(action,varargin)

% TL_TASK_DLG manages the user interface of TargetLink Task block
%
% SYNTAX dlgInfo = TLTaskDlg('GetDlgInfo');
%   gets dialog info of TargetLink Task block
%
%   INPUT ARGUMENTS
%   -/-      
%
%   OUTPUT ARGUMENTS
%   dlgInfo     dialog information contains pageNames etc.
%
% SYNTAX [sheetDims, ctrlPos] = TLTaskDlg('CtrlPositions', pageName, commonGeom, dlgInfo, sheetDims);
%   calculates the control positions of all controls of dialog page: <pageName>
%
%   INPUT ARGUMENTS
%   pageName        name of current page
%   commonGeom      common geometry data
%   dlgInfo         dialog information contains pageNames etc.
%   sheetDims       dimension of sheet
%
%   OUTPUT ARGUMENTS
%   sheetDims       modified dimension of sheet
%   ctrlPos         positions of controls
%
% SYNTAX dlgdata = TLTaskDlg('Create', pageName, dlgfig, dlgdata);
%   creates all controls of dialog page: <pageName>
%
%   INPUT ARGUMENTS
%   pageName        name of current page
%   dlgfig          figure handle
%   dlgdata         dialog data
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%
% SYNTAX [dlgdata,bModified] = TLTaskDlg('Manage', pageName, dlgfig, dlgdata, pageAction);
%   manages all actions of dialog page: <pageName>
%
%   INPUT ARGUMENTS
%   pageName        name of current page
%   dlgfig          figure handle
%   dlgdata         dialog data
%   pageAction      modified control of current page
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%   bModified       flag = 1, if dialog data are modified, =0 otherwise
%
% SYNTAX dlgdata = TLTaskDlg('Update', dlgfig, dlgdata, pageNum);
%   updates all controls of dialog page: <pageNum>
%
%   INPUT ARGUMENTS
%   dlgfig          figure handle
%   dlgdata         dialog data
%   pageNum         number of current page
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%
% SYNTAX TLTaskDlg('Apply', dlgfig, dlgdata);
%   writes current blockdata to block and DD
%
%   INPUT ARGUMENTS
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%
%   OUTPUT ARGUMENTS
%   - / -


% Author(s): D. Andoleit, T. Pietzsch
% $RCSfile: TLTaskDlg.m $
% $ProjectName: e:/ARC/Components/HostSW/SimulinkBlocksets/TLBlocksets/MultirateBlockset/MultirateBlockset_UI/Sources/MSrc/project.pj $
% $Revision: 1.17 $
% $Date: 2011/07/25 10:59:57MESZ $
%
% Copyright ?2011 dSPACE GmbH. All rights reserved.


switch action
    case 'GetDlgInfo'
        hBlock = varargin{1};
        dlgInfo = tl_get_dlginfodefaults('rtos');
        titleName = 'Task';
        pathinfo = tl_pathinfo(hBlock);
        dlgInfo.title = sprintf('TargetLink %s: %s', titleName, pathinfo.shortDisplayName);
        dlgInfo.pageNames   = {
            'Task'};
        varargout{1} = dlgInfo;
        varargout{2} = get_tlcg_data(hBlock);

    case 'CtrlPositions'
        pageName     = varargin{1};
        commonGeom   = varargin{2};
        sheetDims    = varargin{4};
        switch pageName
            case 'Task'
                [sheetDims, ctrlPos] = FcnCalcTaskControlPositions(commonGeom);
        end
        varargout{1} = sheetDims;
        varargout{2} = ctrlPos;

    case 'Create',
        pageName = varargin{1};
        dlgfig   = varargin{2};
        dlgdata  = varargin{3};
        pageNum  = strmatch(pageName, dlgdata.pageNames, 'exact');
        switch pageName
            case 'Task'
                dlgdata = FcnCreateTaskControls(pageNum,dlgfig,dlgdata);
        end
        dlgdata.pageData{pageNum}.ctrlPos = [];
        varargout{1} = dlgdata;

    case 'Manage',
        pageName   = varargin{1};
        dlgfig     = varargin{2};
        dlgdata    = varargin{3};
        pageAction = varargin{4};
        pageNum    = strmatch(pageName,dlgdata.pageNames,'exact');
        switch pageName
            case 'Task'
                [dlgdata, bModified] = ...
                    FcnManageTaskControls(pageNum,dlgfig,dlgdata,pageAction);
        end
        varargout{1} = dlgdata;
        varargout{2} = bModified;

    case 'Update'
        dlgfig    = varargin{1};
        dlgdata   = varargin{2};
        pageNum   = varargin{3};

        pageName  = dlgdata.pageNames{pageNum};

        switch pageName
            case 'Task'
                dlgdata = FcnUpdateTaskControls(dlgdata, dlgfig, pageNum);
        end
        varargout{1} = dlgdata;

    case 'Apply'
        dlgdata = varargin{2};
        bClose   = varargin{3};
        FcnApply(dlgdata);
        [dlgdata, bClose] = tl_apply_blockdata(dlgdata, bClose);
        varargout{1} = dlgdata;
        varargout{2} = bClose;

    otherwise
        error(['Invalid action: "' action '"']);
end


%-----------------------------------------------------------------------------------------
% FcnCalcTaskControlPositions calculates positions for all task controls
%
% INPUT ARGUMENTS
%   commonGeom		common geometry values
%
% OUTPUT ARGUMENTS
%   sheetDims		dimension of sheet
%   ctrlPos		calculated positios of al controls
%
% HINT:
% Positions are calculated from the bottom left of the fig to avoid
% dependencies on figure size
%-----------------------------------------------------------------------------------------
function [sheetDims, ctrlPos] = FcnCalcTaskControlPositions(commonGeom)

strings_and_styles = {...
    'Use activating alarm: ', 	    'text';...
    repmat('m',1,24),               'edit'; ...
    ' Delete Alarm ',               'pushbutton'; ...
    '  . . .   '                    'text'; ...
    ' Manage Events '               'pushbutton'; ...
    '+'                             'pushbutton'};

[taskLabelSize, ...
    taskPopupSize, ...
    deleteTaskButtonSize, ...
    dotButtonSize, ...
    manageButtonSize, ...
    upButtonSize] = ...
    ds_get_uicontrol_sizes(commonGeom, strings_and_styles);

widths = [ ...
    taskLabelSize(1), ...      % max of label width in first column
    taskPopupSize(1), ...
    manageButtonSize(1)];
[col,colWidth,colDelta,rowDelta] = ds_get_gui_columns(widths,commonGeom);

% define pixel width for a small gap
smallGap = colDelta/5;

% finetune some results
upButtonSize = upButtonSize * diag([1 0.5]);
if (2 * deleteTaskButtonSize(1) + colDelta/3) > taskPopupSize(1)
    taskPopupSize(1) = 2 * deleteTaskButtonSize(1) + colDelta/3;
else
    deleteTaskButtonSize(1) = (taskPopupSize(1) - colDelta/3) / 2;
end

%-----------------------------------------------------------
% OSEK properties group box
%-----------------------------------------------------------
cx = commonGeom.figSideEdgeBuffer + commonGeom.sheetSideEdgeBuffer;
cy = commonGeom.bottomSheetOffset + ...
    commonGeom.sheetBottomEdgeBuffer;

osekPropertiesGroupboxWidth = col(end) + ...
    colWidth(end) + ...
    commonGeom.frameSideEdgeBuffer;

osekPropertiesGroupboxHeight = ...
    commonGeom.frameTopEdgeBuffer + ...
    4 * rowDelta + ...
    5 * commonGeom.editHeight + ...
    commonGeom.frameBottomEdgeBuffer;

ctrlPos.osekPropertiesGroupbox =  ...
    [cx cy  osekPropertiesGroupboxWidth osekPropertiesGroupboxHeight];

%-----------------------------------------------------------
% 5th row
cy = commonGeom.frameBottomEdgeBuffer;

% autostart
cx = col(2);
ctrlPos.autostartCheckbox = [cx cy taskLabelSize];

cx = col(3);
ctrlPos.vendorSettingsButton = [cx cy manageButtonSize];

%-----------------------------------------------------------
% 4th row
cy = cy + taskPopupSize(2) + rowDelta;

% activation
cx = col(1);
ctrlPos.activationsLabel = [cx cy taskLabelSize];

cx = col(2);
activationsEditSize(1) = taskPopupSize(1) - upButtonSize(1) - smallGap;
activationsEditSize(2) = taskPopupSize(2);
ctrlPos.activationsEdit = [cx cy activationsEditSize];

cx = col(2) + activationsEditSize(1) + smallGap;
ctrlPos.activationsUpButton = [cx cy + 0.5 * commonGeom.editHeight upButtonSize];
ctrlPos.activationsDownButton = [cx cy upButtonSize];

%-----------------------------------------------------------
% 3th row
cy = cy + taskPopupSize(2) + rowDelta;

% alarm
cx = col(1);
ctrlPos.alarmLabel = [cx cy taskLabelSize];

cx = col(2);
ctrlPos.alarmPopup = [cx cy taskPopupSize];

cx = col(3);
ctrlPos.manageAlarmsButton = [cx cy manageButtonSize];

%-----------------------------------------------------------
% 2nd row
cy = cy + taskPopupSize(2) + rowDelta;

% use activating alarm
cx = col(1);
ctrlPos.useActivatingAlarmLabel = [cx cy taskLabelSize];

cx = col(2);
ctrlPos.useActivatingAlarmPopup = [cx cy taskPopupSize];

%-----------------------------------------------------------
% 1st row
cy = cy + taskPopupSize(2) + rowDelta;

% event
cx = col(1);
ctrlPos.eventLabel = [cx cy taskLabelSize];

cx = col(2);
ctrlPos.eventPopup = [cx cy taskPopupSize];

cx = col(3);
ctrlPos.manageEventsButton = [cx cy manageButtonSize];

%-----------------------------------------------------------
% mltirate common properties group box
%-----------------------------------------------------------
cx = ctrlPos.osekPropertiesGroupbox(1);
cy = ctrlPos.osekPropertiesGroupbox(2) + ctrlPos.osekPropertiesGroupbox(4) + commonGeom.textHeight;

multirateGroupboxWidth = osekPropertiesGroupboxWidth;

multirateGroupboxHeight = ...
    commonGeom.frameTopEdgeBuffer + ...
    rowDelta + ...
    2 * commonGeom.editHeight + ...
    commonGeom.frameBottomEdgeBuffer;
ctrlPos.multirateGroupbox =  ...
    [cx cy  multirateGroupboxWidth multirateGroupboxHeight];

%-----------------------------------------------------------
% 2nd row
cy = commonGeom.frameBottomEdgeBuffer;

% peemptive label
cx = col(1);
ctrlPos.preemptiveLabel = [cx cy taskLabelSize];

% preemptive edit
cx = col(2);
ctrlPos.preemptivePopup = [cx cy taskPopupSize];

%-----------------------------------------------------------
% 1st row
cy = cy + taskPopupSize(2) + rowDelta;

% priority label
cx = col(1);
ctrlPos.priorityLabel = [cx cy taskLabelSize];

% priority edit
cx = col(2);
ctrlPos.priorityEdit = [cx cy taskPopupSize];

%-----------------------------------------------------------
% task group box
%-----------------------------------------------------------
cx = ctrlPos.multirateGroupbox(1);
cy = ctrlPos.multirateGroupbox(2) + ctrlPos.multirateGroupbox(4) + commonGeom.textHeight;

taskGroupboxWidth = osekPropertiesGroupboxWidth;

taskGroupboxHeight = ...
    commonGeom.frameTopEdgeBuffer + ...
    4 * rowDelta + ...
    5 * commonGeom.editHeight + ...
    commonGeom.frameBottomEdgeBuffer;
ctrlPos.taskGroupbox =  ...
    [cx cy  taskGroupboxWidth taskGroupboxHeight];

%-----------------------------------------------------------
% 5th row
cy = commonGeom.frameBottomEdgeBuffer;

% function class
cx = col(1);
ctrlPos.functionClassLabel = [cx cy taskLabelSize];

cx = col(2);
ctrlPos.functionClassEdit = [cx cy taskPopupSize];

cx = col(3);
ctrlPos.functionClassDotButton = [cx cy dotButtonSize(1) taskPopupSize(2)];

%-----------------------------------------------------------
% 4th row
cy = cy + taskPopupSize(2) + rowDelta;

% code file
cx = col(1);
ctrlPos.moduleLabel = [cx cy taskLabelSize];

cx = col(2);
ctrlPos.moduleEdit = [cx cy taskPopupSize];

cx = col(3);
ctrlPos.moduleDotButton = [cx cy dotButtonSize(1) taskPopupSize(2)];

%-----------------------------------------------------------
% 3th row
cy = cy + taskPopupSize(2) + rowDelta;

% description
cx = col(1);
ctrlPos.descriptionLabel = [cx cy taskLabelSize];

cx = col(2);
ctrlPos.descriptionEdit = [cx cy taskPopupSize];

%-----------------------------------------------------------
% 2nd row
cy = cy + taskPopupSize(2) + rowDelta;

% new task push button
cx = col(2);
ctrlPos.newTaskButton = [cx cy deleteTaskButtonSize];

% delete task push button
cx = col(2) + deleteTaskButtonSize(1) + colDelta/3;
ctrlPos.deleteTaskButton = [cx cy deleteTaskButtonSize];

%-----------------------------------------------------------
% 1st row
cy = cy + deleteTaskButtonSize(2) + rowDelta;

% task
cx = col(1);
ctrlPos.taskLabel = [cx cy taskLabelSize];

cx = col(2);
ctrlPos.taskPopup = [cx cy taskPopupSize];

% sheet dimensions
sheetDims(1) = ctrlPos.taskGroupbox(3) + ...
    2 * commonGeom.frameSideEdgeBuffer;

sheetDims(2) = ctrlPos.taskGroupbox(4) + ...
    commonGeom.textHeight + ...
    ctrlPos.multirateGroupbox(4) + ...
    commonGeom.textHeight + ...
    ctrlPos.osekPropertiesGroupbox(4) + ...
    commonGeom.textHeight + ...
    commonGeom.sheetBottomEdgeBuffer;


%-----------------------------------------------------------------------------------------
% FcnCreateTaskControls creates all task controls
%
% INPUT ARGUMENTS
%   pageNum 	number of current page (=1 for task page)
%   dlgfig 	dialg figure handle
%   dlgdata 	dialog data
%
% OUTPUT ARGUMENTS
%   dlgdata 	modified diaog data
%-----------------------------------------------------------------------------------------
function dlgdata = FcnCreateTaskControls(pageNum,dlgfig,dlgdata)

ctrlPos    = dlgdata.pageData{pageNum}.ctrlPos;
Children   = dlgdata.pageData{pageNum}.children;

% task groupbox
Children.taskGroupbox = uipanel( ...
    'Parent',            dlgfig, ...
    'Title',            {'Task definition'}, ...
    'Units',            'pixels', ...
    'Position',          ctrlPos.taskGroupbox);

% task popup
Children.taskLabel = uicontrol( ...
    'Parent',             Children.taskGroupbox, ...
    'Style',              'text', ...
    'String',             'Task name:', ...
    'Position',           ctrlPos.taskLabel);

Children.taskPopup = uicontrol( ...
    'Parent',             Children.taskGroupbox, ...
    'BackgroundColor',    'w', ...
    'Style',              'Popupmenu', ...
    'String',             ' ', ...
    'Position',           ctrlPos.taskPopup);

% new / delete task button
Children.newTaskButton = uicontrol( ...
    'Parent',            Children.taskGroupbox, ...
    'Style',             'pushbutton', ...
    'String',            'New Task', ...
    'Position',          ctrlPos.newTaskButton);

Children.deleteTaskButton = uicontrol( ...
    'Parent',            Children.taskGroupbox, ...
    'Style',             'pushbutton', ...
    'String',            'Delete Task', ...
    'Position',          ctrlPos.deleteTaskButton);

Children.descriptionLabel = uicontrol( ...
    'Parent',             Children.taskGroupbox, ...
    'Style',              'text', ...
    'String',             'Description:', ...
    'Position',           ctrlPos.descriptionLabel);

Children.descriptionEdit = uicontrol( ...
    'Parent',             Children.taskGroupbox, ...
    'BackgroundColor',    'w', ...
    'Style',              'edit', ...
    'Position',           ctrlPos.descriptionEdit);

Children.moduleLabel = uicontrol( ...
    'Parent',             Children.taskGroupbox, ...
    'Style',              'text', ...
    'String',             'Module:', ...
    'Position',           ctrlPos.moduleLabel);

Children.moduleEdit = uicontrol( ...
    'Parent',             Children.taskGroupbox, ...
    'BackgroundColor',    'w', ...
    'Style',              'edit', ...
    'Position',           ctrlPos.moduleEdit);

Children.moduleDotButton = uicontrol( ...
    'Parent',            Children.taskGroupbox, ...
    'Style',             'pushbutton', ...
    'String',            ' . . . ', ...
    'Position',          ctrlPos.moduleDotButton);

Children.functionClassLabel = uicontrol( ...
    'Parent',             Children.taskGroupbox, ...
    'Style',              'text', ...
    'String',             'Function class:', ...
    'Position',           ctrlPos.functionClassLabel);

Children.functionClassEdit = uicontrol( ...
    'Parent',             Children.taskGroupbox, ...
    'BackgroundColor',    'w', ...
    'Style',              'edit', ...
    'Position',           ctrlPos.functionClassEdit);

Children.functionClassDotButton = uicontrol( ...
    'Parent',            Children.taskGroupbox, ...
    'Style',             'pushbutton', ...
    'String',            ' . . . ', ...
    'Position',          ctrlPos.functionClassDotButton);

% multirate common properties groupbox
Children.multirateGroupbox = uipanel( ...
    'Parent',            dlgfig, ...
    'Title',            {'Multirate common properties'}, ...
    'Units',            'pixels', ...
    'Position',          ctrlPos.multirateGroupbox);

% priority
Children.priorityLabel = uicontrol( ...
    'Parent',             Children.multirateGroupbox, ...
    'Style',              'text', ...
    'String',             'Priority:', ...
    'Position',           ctrlPos.priorityLabel);

Children.priorityEdit = uicontrol( ...
    'Parent',             Children.multirateGroupbox, ...
    'BackgroundColor',    'w', ...
    'Style',              'edit', ...
    'Position',           ctrlPos.priorityEdit);

% preemptive
Children.preemptiveLabel = uicontrol( ...
    'Parent',             Children.multirateGroupbox, ...
    'Style',              'text', ...
    'String',             'Preemptive:', ...
    'Position',           ctrlPos.preemptiveLabel);

Children.preemptivePopup = uicontrol( ...
    'Parent',             Children.multirateGroupbox, ...
    'BackgroundColor',    'w', ...
    'Style',              'Popupmenu', ...
    'String',             {'FULL','NON'}, ...
    'Position',           ctrlPos.preemptivePopup);

% OSEK properties groupbox
Children.osekPropertiesGroupbox = uipanel( ...
    'Parent',            dlgfig, ...
    'Title',            {'OSEK properties'}, ...
    'Units',            'pixels', ...
    'Position',          ctrlPos.osekPropertiesGroupbox);

% event
Children.eventLabel = uicontrol( ...
    'Parent',             Children.osekPropertiesGroupbox, ...
    'Style',              'text', ...
    'String',             'Event:', ...
    'Position',           ctrlPos.eventLabel);

Children.eventPopup = uicontrol( ...
    'Parent',             Children.osekPropertiesGroupbox, ...
    'BackgroundColor',    'w', ...
    'Style',              'Popupmenu', ...
    'String',             ' ', ...
    'Position',           ctrlPos.eventPopup);

Children.manageEventsButton = uicontrol( ...
    'Parent',            Children.osekPropertiesGroupbox, ...
    'Style',             'pushbutton', ...
    'String',            'Manage Events', ...
    'Position',          ctrlPos.manageEventsButton);

% alarm
Children.useActivatingAlarmLabel = uicontrol( ...
    'Parent',             Children.osekPropertiesGroupbox, ...
    'Style',              'text', ...
    'String',             'Use activating alarm:', ...
    'Position',           ctrlPos.useActivatingAlarmLabel);

Children.useActivatingAlarmPopup = uicontrol( ...
    'Parent',             Children.osekPropertiesGroupbox, ...
    'BackgroundColor',    'w', ...
    'Style',              'Popupmenu', ...
    'String',             ' ', ...
    'Position',           ctrlPos.useActivatingAlarmPopup);

Children.alarmLabel = uicontrol( ...
    'Parent',             Children.osekPropertiesGroupbox, ...
    'Style',              'text', ...
    'String',             'Alarm:', ...
    'Position',           ctrlPos.alarmLabel);

Children.alarmPopup = uicontrol( ...
    'Parent',             Children.osekPropertiesGroupbox, ...
    'BackgroundColor',    'w', ...
    'Style',              'Popupmenu', ...
    'String',             ' ', ...
    'Position',           ctrlPos.alarmPopup);

Children.manageAlarmsButton = uicontrol( ...
    'Parent',            Children.osekPropertiesGroupbox, ...
    'Style',             'pushbutton', ...
    'String',            'Manage Alarms', ...
    'Position',          ctrlPos.manageAlarmsButton);

Children.activationsLabel = uicontrol( ...
    'Parent',             Children.osekPropertiesGroupbox, ...
    'Style',              'text', ...
    'String',             'Activations:', ...
    'Position',           ctrlPos.activationsLabel);

userData = struct('min', 1, 'max', Inf);
Children.activationsEdit = uicontrol( ...
    'Parent',             Children.osekPropertiesGroupbox, ...
    'BackgroundColor',    'w', ...
    'Style',              'edit', ...
    'Position',           ctrlPos.activationsEdit, ...
    'UserData',           userData);

Children.activationsUpButton = uicontrol( ...
    'Parent',             Children.osekPropertiesGroupbox, ...
    'Style',              'pushbutton', ...
    'String',             '+', ...
    'Position',           ctrlPos.activationsUpButton);

Children.activationsDownButton = uicontrol( ...
    'Parent',             Children.osekPropertiesGroupbox, ...
    'Style',              'pushbutton', ...
    'String',             '-', ...
    'Position',           ctrlPos.activationsDownButton);

Children.autostartCheckbox = uicontrol( ...
    'Parent',             Children.osekPropertiesGroupbox, ...
    'Style',              'checkbox', ...
    'String',             'Autostart', ...
    'Position',           ctrlPos.autostartCheckbox);

Children.vendorSettingsButton = uicontrol( ...
    'Parent',            Children.osekPropertiesGroupbox, ...
    'Style',             'pushbutton', ...
    'String',            'Vendor Settings', ...
    'Position',          ctrlPos.vendorSettingsButton);

dlgdata.pageData{pageNum}.children = Children;

dlgdata = FcnGetTaskDataFromDD(dlgdata);


%-----------------------------------------------------------------------------------------
% FcnManageTaskControls manage control actions of task page
%
% INPUT ARGUMENTS
%   pageNum     number of current page
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%   pageAction  action at one control of current page
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%   bModified   flag = 1, if dialog data are modified, =0 otherwise
%-----------------------------------------------------------------------------------------
function [dlgdata, bModified] = FcnManageTaskControls(pageNum,dlgfig,dlgdata,pageAction)    %#ok

Children   = dlgdata.pageData{pageNum}.children;

% determine the current task control
currentTask       = dlgdata.data.task;
taskList          = dlgdata.taskInfo.dataStrings;
currentTaskIdx    = find(strcmp(currentTask,taskList));

switch pageAction
    case 'taskPopup'
        newTaskIdx = get(Children.taskPopup, 'Value');
        if ~isequal(currentTaskIdx, newTaskIdx)
            if isempty(currentTaskIdx)
                % current task is not found in task list
                newTaskIdx = newTaskIdx - 1;
                if newTaskIdx == 0
                    bModified = 0;
                    return
                end
            end
            dlgdata.data.task = dlgdata.taskInfo.dataStrings{newTaskIdx};
            bModified = 1;
        end
    case 'newTaskButton'
        [dlgdata, bModified] = FcnNewTask(dlgdata);
    case 'deleteTaskButton'
        dlgdata = FcnDeleteTask(dlgdata);
        bModified = 1;
    case 'descriptionEdit'
        dlgdata.taskData(currentTaskIdx).description = ...
            get(Children.descriptionEdit, 'String');
        dlgdata.taskInfo.editedTask = unique([dlgdata.taskInfo.editedTask,currentTask]);
        bModified = 1;
    case 'moduleEdit'
        dlgdata.taskData(currentTaskIdx).module = ...
            get(Children.moduleEdit, 'String');
        dlgdata.taskInfo.editedTask = unique([dlgdata.taskInfo.editedTask,currentTask]);
        bModified = 1;
    case 'moduleDotButton'
        dlgdata.taskData(currentTaskIdx).module = ...
            dsdd( 'SelectObject', ...
            'CurrentPath',     dlgdata.taskData(currentTaskIdx).module, ...
            'ObjectKind',      'Module');
        dlgdata.taskInfo.editedTask = unique([dlgdata.taskInfo.editedTask,currentTask]);
        bModified = 1;
    case 'functionClassEdit'
        functionClassStr = tl_deblank(get(Children.functionClassEdit, 'String'), 2);
        if isempty(functionClassStr),
            functionClassStr = 'default';
        end
        dlgdata.taskData(currentTaskIdx).functionclass = functionClassStr;
        dlgdata.taskInfo.editedTask = unique([dlgdata.taskInfo.editedTask,currentTask]);
        bModified = 1;
    case 'functionClassDotButton'
        dlgdata.taskData(currentTaskIdx).functionclass = ...
            dsdd( 'SelectObject', ...
            'CurrentPath',     dlgdata.taskData(currentTaskIdx).functionclass, ...
            'ObjectKind',      'FunctionClass');
        dlgdata.taskInfo.editedTask = unique([dlgdata.taskInfo.editedTask,currentTask]);
        bModified = 1;
    case 'priorityEdit'
        dlgdata.taskData(currentTaskIdx).priority = ...
            get(Children.priorityEdit, 'String');
        dlgdata.taskInfo.editedTask = unique([dlgdata.taskInfo.editedTask,currentTask]);
        bModified = 1;
    case 'preemptivePopup'
        % preemptive property in DD is boolean
        dlgdata.taskData(currentTaskIdx).preemptive = get(Children.preemptivePopup, 'Value') - 1;
        dlgdata.taskInfo.editedTask = unique([dlgdata.taskInfo.editedTask,currentTask]);
        bModified = 1;
    case 'eventPopup'
        currentEventIdx = get(Children.eventPopup, 'Value');
        eventList = dlgdata.taskData(currentTaskIdx).eventStrings;
        dlgdata.taskData(currentTaskIdx).event = eventList{currentEventIdx};
        dlgdata.data.event = eventList{currentEventIdx};
        dlgdata.taskInfo.editedTask = unique([dlgdata.taskInfo.editedTask,currentTask]);
        bModified = 1;
    case 'manageEventsButton'
        dlgdata = FcnManageEvent(dlgdata);
        bModified = 1;
    case 'useActivatingAlarmPopup'
        useActivatingAlarmIdx = get(Children.useActivatingAlarmPopup, 'Value');
        useActivatingAlarmList = {'DEFAULT', 'ON', 'OFF'};
        dlgdata.taskData(currentTaskIdx).useactivatingalarm = useActivatingAlarmList{useActivatingAlarmIdx};
        dlgdata.taskInfo.editedTask = unique([dlgdata.taskInfo.editedTask,currentTask]);
        bModified = 1;
    case 'alarmPopup'
        currentAlarmIdx = get(Children.alarmPopup, 'Value');
        alarmList = dlgdata.taskData(currentTaskIdx).alarmStrings;
        dlgdata.taskData(currentTaskIdx).alarm = alarmList{currentAlarmIdx};
        dlgdata.taskInfo.editedTask = unique([dlgdata.taskInfo.editedTask,currentTask]);
        bModified = 1;
    case 'manageAlarmsButton'
        dlgdata = FcnManageAlarms(dlgdata,currentTaskIdx);
        bModified = 1;
    case {'activationsEdit','activationsUpButton','activationsDownButton'}
        userData = get(Children.activationsEdit, 'UserData');
        userData.min = eval(['Children.' pageAction]);
        [activationsChar,bModified] = ...
            tl_handle_editupdown('Manage', ...
            num2str(dlgdata.taskData(currentTaskIdx).activations), ...
            [Children.activationsEdit,Children.activationsUpButton,Children.activationsDownButton], ...
            eval(['Children.' pageAction]));
        activationsNum = str2num(activationsChar); %#ok<ST2NM>
        if ~isempty(activationsNum) && ~isequalwithequalnans(activationsNum, NaN)
            dlgdata.taskData(currentTaskIdx).activations = activationsNum;
        end
        dlgdata.taskInfo.editedTask = unique([dlgdata.taskInfo.editedTask,currentTask]);
    case 'autostartCheckbox'
        dlgdata.taskData(currentTaskIdx).autostart = ...
            get(Children.autostartCheckbox, 'Value');
        bModified = 1;
        dlgdata.taskInfo.editedTask = unique([dlgdata.taskInfo.editedTask,currentTask]);
    case 'vendorSettingsButton'
        dlgdata = FcnVendorSettings(dlgdata);
        bModified = 1;
end


%--------------------------------------------------------------------------
% FcnUpdateTaskControls updates the controls of the task tab
%
% INPUT ARGUMENTS
%   dlgdata     dialog data
%   dlgfig      figure handle of dialog
%   pageNum     page Number (=1 for task page)
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%--------------------------------------------------------------------------

function dlgdata = FcnUpdateTaskControls(dlgdata, dlgfig, pageNum)          %#ok

Children = dlgdata.pageData{pageNum}.children;

taskData = dlgdata.taskData;

currentTask    = dlgdata.data.task;
taskList       = dlgdata.taskInfo.dataStrings;
currentTaskIdx = find(strcmp(currentTask,taskList));

enableOn = 'on';
if ~dlgdata.bIsFullVs
    enableOn = 'inactive';
end

% default control status for controls of task definition groupbox
taskPopupCtrlStatus               = struct('enable', enableOn, 'value', 1, 'string', {taskList});
newTaskButtonCtrlStatus           = struct('enable', enableOn);                                     %#ok
deleteTaskButtonCtrlStatus        = struct('enable', enableOn);
descriptionEditCtrlStatus         = struct('enable', enableOn, 'string', '');
moduleEditCtrlStatus              = struct('enable', enableOn, 'string', '');
moduleDotButtonCtrlStatus         = struct('enable', enableOn);
functionClassEditCtrlStatus       = struct('enable', enableOn, 'string', 'default ');
functionClassDotButtonCtrlStatus  = struct('enable', enableOn);

% default control status for controls of multirate common properties groupbox
priorityEditCtrlStatus            = struct('enable', enableOn, 'string', '');
preemptivePopupCtrlStatus         = struct('enable', enableOn, 'value', 1);
preemptivePopupCtrlStatus.string  = {'NON' 'FULL'};

% default control status for controls of OSEK properties groupbox
eventPopupCtrlStatus              = struct('enable', enableOn, 'value', 1, 'string', 'none');
manageEventsButtonCtrlStatus      = struct('enable', enableOn);
useActivatingAlarmPopupCtrlStatus = struct('enable', enableOn, 'value', 1);
useActivatingAlarmPopupCtrlStatus.string  = {'DEFAULT' 'ON' 'OFF'};
alarmPopupCtrlStatus              = struct('enable', enableOn, 'value', 1, 'string', ' ');
manageAlarmsButtonCtrlStatus      = struct('enable', enableOn);
activationsEditCtrlStatus         = struct('enable', enableOn, 'string', '1');
activationsUpButtonCtrlStatus     = struct('enable', enableOn);
activationsDownButtonCtrlStatus   = struct('enable', enableOn);
autostartCheckboxCtrlStatus       = struct('enable', enableOn, 'value', 0);
vendorSettingsButtonCtrlStatus    = struct('enable', enableOn);

% if not valid disable most of the controls
if isempty(currentTaskIdx) ...
        || (~isempty(currentTaskIdx) && taskData(currentTaskIdx).bValid == 0),
    if isempty(currentTaskIdx)
        taskPopupCtrlStatus.string   = [{' '}, taskList];
    else
        taskPopupCtrlStatus.iserror = 1;
    end
    deleteTaskButtonCtrlStatus.enable = 'off';
    descriptionEditCtrlStatus.enable = 'inactive';
    moduleEditCtrlStatus.enable = 'inactive';
    moduleDotButtonCtrlStatus.enable = 'off';
    functionClassEditCtrlStatus.enable = 'inactive';
    functionClassDotButtonCtrlStatus.enable = 'off';

    priorityEditCtrlStatus.enable = 'inactive';
    preemptivePopupCtrlStatus.enable = 'inactive';

    eventPopupCtrlStatus.enable = 'inactive';
    manageEventsButtonCtrlStatus.enable = 'off';
    useActivatingAlarmPopupCtrlStatus.enable = 'inactive';
    alarmPopupCtrlStatus.enable = 'inactive';
    manageAlarmsButtonCtrlStatus.enable = 'off';
    activationsEditCtrlStatus.enable = 'inactive';
    activationsUpButtonCtrlStatus.enable = 'off';
    activationsDownButtonCtrlStatus.enable = 'off';
    autostartCheckboxCtrlStatus.enable = 'off';
    vendorSettingsButtonCtrlStatus.enable = 'off';
else
    taskPopupCtrlStatus.value               = currentTaskIdx;
    descriptionEditCtrlStatus.string        = dlgdata.taskData(currentTaskIdx).description;
    moduleEditCtrlStatus.string             = dlgdata.taskData(currentTaskIdx).module;
    moduleEditCtrlStatus.iserror = ~isempty(dlgdata.taskData(currentTaskIdx).module) ...
        && ~dsdd('exist', ['/Pool/Modules/' dlgdata.taskData(currentTaskIdx).module]);
    if ~strcmp(dlgdata.taskData(currentTaskIdx).functionclass, 'default')
        functionClassEditCtrlStatus.string      = dlgdata.taskData(currentTaskIdx).functionclass;
    end
    priorityEditCtrlStatus.string           = dlgdata.taskData(currentTaskIdx).priority;
    preemptivePopupCtrlStatus.value         = dlgdata.taskData(currentTaskIdx).preemptive + 1;
    useActivatingAlarmPopupCtrlStatus.value = find(strcmp(dlgdata.taskData(currentTaskIdx).useactivatingalarm,{'DEFAULT' 'ON' 'OFF'}));
    activationsEditCtrlStatus.string        = num2str(dlgdata.taskData(currentTaskIdx).activations);
    activationsDownButtonCtrlStatus.enable  = flag2str(dlgdata.taskData(currentTaskIdx).activations > 1);
    autostartCheckboxCtrlStatus.value       = dlgdata.taskData(currentTaskIdx).autostart;

    % update event selection popup
    eventList = FcnGetEventList(['/Pool/RTOS/Tasks/',currentTask]);
    eventName = dlgdata.data.event;
    eventIdx  = find(strcmp(eventName,eventList));
    eventPopupCtrlStatus.value = eventIdx;
    if isempty(eventIdx),
        eventList = [{eventName},eventList];
        eventIdx = 1;
        eventPopupCtrlStatus.iserror = 1;
    else
        eventPopupCtrlStatus.iserror = 0;
    end
    dlgdata.taskData(currentTaskIdx).eventStrings = eventList;
    eventPopupCtrlStatus.value = eventIdx;
    eventPopupCtrlStatus.string = eventList;
    dlgdata.data.event = eventName;

    % update the alarm selection popup
    if strcmp(taskData(currentTaskIdx).useactivatingalarm, 'ON')
        alarmList = FcnGetAlarmList(currentTask,eventName);
        alarmName = taskData(currentTaskIdx).alarm;
        if isempty(alarmName),
            alarmName = ' ';
        end
        alarmIdx  = find(strcmp(alarmName,alarmList), 1);
        if isempty(alarmIdx),
            alarmIdx = 1;
            alarmList = [{alarmName},alarmList];
            alarmPopupCtrlStatus.iserror = 1;
        end
        alarmPopupCtrlStatus.value = alarmIdx;
    else
        % disable alarm selection controls
        alarmList = ' ';
        alarmPopupCtrlStatus.enable = 'inactive';
        manageAlarmsButtonCtrlStatus.enable = 'off';
    end
    alarmPopupCtrlStatus.string   = alarmList;
    dlgdata.taskData(currentTaskIdx).alarmStrings = alarmList;

    % check existence of function class
    functionClass = taskData(currentTaskIdx).functionclass;
    if ~dsdd('Exist',functionClass,'Parent','/Pool/FunctionClasses') ...
            && ~strcmp(functionClass,'default'),
        functionClassEditCtrlStatus.iserror = 1;
    end
end


ctrlsList = {
    'taskPopup' ...
    'newTaskButton' ...
    'deleteTaskButton' ...
    'descriptionEdit' ...
    'moduleEdit' ...
    'moduleDotButton' ...
    'functionClassEdit' ...
    'functionClassDotButton' ...
    'priorityEdit' ...
    'preemptivePopup' ...
    'eventPopup' ...
    'manageEventsButton' ...
    'useActivatingAlarmPopup' ...
    'alarmPopup' ...
    'manageAlarmsButton' ...
    'activationsEdit' ...
    'activationsUpButton' ...
    'activationsDownButton' ...
    'autostartCheckbox' ...
    'vendorSettingsButton'};

for ctrlsNo=1:length(ctrlsList)
    ctrl = Children.(ctrlsList{ctrlsNo});
    UserData = get(ctrl, 'UserData');
    UserData.ctrlStatus = eval([ctrlsList{ctrlsNo} 'CtrlStatus']);
    set(ctrl, 'UserData', UserData);
end
TLSetCtrlsStatus(dlgfig,Children, ctrlsList);


%--------------------------------------------------------------------------
% FcnApply writes current block data to the DD
%
% INPUT ARGUMENTS
%   dlgdata     dialog data
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%--------------------------------------------------------------------------
function dlgdata = FcnApply(dlgdata)

taskInfo = dlgdata.taskInfo;

% DataDictionary path for tasks
ddTaskPath = '/Pool/RTOS/Tasks';

% first delete tasks
for m = 1:length(taskInfo.deletedTask),
    dsdd('delete',[ddTaskPath,'/',taskInfo.deletedTask{m}]);
end

% add new tasks
for m = 1:length(taskInfo.newTask),
    if ~dsdd('Exist',taskInfo.newTask{m}, ...
            'Parent',            '/Pool/RTOS/Tasks', ...
            'ObjectKind',        'task')
        [hTaskObject,errCode] = dsdd('Create',taskInfo.newTask{m}, ...
            'Parent',            '/Pool/RTOS/Tasks', ...
            'ObjectKind',        'task');
        if dsdd_check_msg(errCode)
            % return if creation failed
            return
        end
    end
    % append created counters to edited counter
    taskInfo.editedTask = [taskInfo.editedTask,taskInfo.newTask(m)];
end

% apply changes of edited tasks
editedTask = unique(taskInfo.editedTask);
for m = 1:length(editedTask),
    currentTaskIdx = strcmp(editedTask{m},taskInfo.dataStrings);
    [bExist,hTaskObject] = dsdd('exist',[ddTaskPath,'/',editedTask{m}]);
    properties = dlgdata.taskData(currentTaskIdx);
    if bExist,
        % description
        errCode = dsdd('SetDescription',hTaskObject,properties.description);
        dsdd_check_msg(errCode);
        
        % code file
        errCode = dsdd('SetModuleRef',hTaskObject,properties.module);
        dsdd_check_msg(errCode);

        % function class
        errCode = dsdd('SetFunctionClassRef',hTaskObject,properties.functionclass);
        dsdd_check_msg(errCode);
        % priority
        % HINT the string 'auto' will be translated into empty matrix by str2num.
        errCode = dsdd('SetPriority',hTaskObject,str2num(properties.priority)); %#ok str2num returns [] for strings (str2double NaN)
        dsdd_check_msg(errCode);
        % preemptive file
        errCode = dsdd('SetPreemptive',hTaskObject,properties.preemptive);
        dsdd_check_msg(errCode);
        % events
        % HINT: This date will be stored as Task block property. But we
        %       need a handle of the corresponding data dictionary object
        if strcmp(properties.event,'none'),
            hAlarmAnchor = hTaskObject;
        else
            [bOk,hEvent] = dsdd('Exist',properties.event, ...
                'Parent','/Pool/RTOS/Events');
            if ~bOk,
                ds_error_msg('Assertion failed: Selected event doesn''t exist!');
                return
            else
                hAlarmAnchor = hEvent;
                % reset alarm properties at task object
                errCode = dsdd('SetUseActivatingAlarm',hTaskObject,'DEFAULT');
                dsdd_check_msg(errCode);
                if dsdd('Exist',hTaskObject,'Property','ActivatingAlarmRef')
                    errCode = dsdd('Delete',hTaskObject,'ActivatingAlarmRef');
                    dsdd_check_msg(errCode);
                end
            end
        end
        % use activating alarms
        dsdd('SetUseActivatingAlarm',hAlarmAnchor,properties.useactivatingalarm);
        dsdd_check_msg(errCode);
        bNoAlarm = ~strcmp(properties.useactivatingalarm, 'ON');
        if bNoAlarm,
            % delete property ActivatingAlarmRef
            if dsdd('exist',hAlarmAnchor,'Property','ActivatingAlarmRef');
                errCode = dsdd('delete',hAlarmAnchor,'ActivatingAlarmRef');
                dsdd_check_msg(errCode);
            end
        else
            % set activating alarm reference
            newAlarmRef = properties.alarm;
            bExist = dsdd('exist',newAlarmRef, ...
                'Parent',   '/Pool/RTOS/Alarms');
            if ~bExist,
                ds_error_msg( ['The selected alarm ''',newAlarmRef,''' for task ', ...
                    '''',editedTask(m),''' couldn''t ', ...
                    'be found in your current Data Dictionary. It ', ...
                    'is strongly recommended that you create the ', ...
                    'missing alarm object or select another existing ', ...
                    'alarm.'], ...
                    'MessageType',     'Warning');
            end
            dsdd('SetActivatingAlarmRef',hAlarmAnchor,newAlarmRef);
        end
        % activation
        errCode = dsdd('SetActivation',hTaskObject,properties.activations);
        dsdd_check_msg(errCode);
        % autostart
        dsdd('SetAutoStart',hTaskObject,properties.autostart);
        dsdd_check_msg(errCode);
    end
end


%--------------------------------------------------------------------------
% FcnGetEventList compile a list of relevant events
%
% INPUT ARGUMENTS
%   hTask         task handle
%
% OUTPUT ARGUMENTS
%   eventList     list of events
%--------------------------------------------------------------------------
function eventList = FcnGetEventList(hTask)

% iterate over all events
eventList = {'none'};
hEventNode = dsdd('GetEvents',hTask);
eventRef = dsdd('GetPropertyNames',hEventNode);
for n = 1:length(eventRef),
    [eventName,errCode] = dsdd('Get',hEventNode,eventRef{n});
    if dsdd_check_msg(errCode),
        % continue with next event
        continue
    end
    % check existence
    if ~dsdd('Exist',eventName,'Parent','/Pool/RTOS/Events'),
        continue
    end
    eventList = [eventList,{eventName}];        %#ok
end


%--------------------------------------------------------------------------
% FcnNewTask creates new task with default data
%
% INPUT ARGUMENTS
%   dlgdata     dialog data
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%   bModified   flag =1, if new alarm is created, =0 otherwise
%--------------------------------------------------------------------------
function [dlgdata, bModified] = FcnNewTask(dlgdata)

% initialize return value
bModified = 0;

% ask user for task name
prompt   = 'Please enter a name for the task.';
dlgTitle = 'Task Name';
lineNum = 1;
newTaskName = tl_deblank(char(inputdlg(prompt,dlgTitle,lineNum)),3);
if isempty(newTaskName),
    return;
else
    [newTaskName,bOk] = ds_check_value(newTaskName,'CIdentifier');
    if ~bOk,
        errMsg = sprintf('Task name "%s" does not comply with rules for C identifier.',newTaskName);
        ds_error_msg( errMsg, ...
            'Title',         'Incompliant Task Name');
        return
    end
end

taskData = dlgdata.taskData;

% check if task name is really new
taskList = dlgdata.taskInfo.dataStrings;
if any(strcmp(newTaskName,taskList));
    return
end

% check if current task is invalid and can be overwritten
currentTask    = dlgdata.data.task;
currentTaskIdx = find(strcmp(currentTask,taskList));
if isempty(currentTaskIdx) || taskData(currentTaskIdx).bValid
    currentTaskIdx = length(taskList) + 1;
end
dlgdata.data.task = newTaskName;

% initialize properties with default values
taskData = FcnSetTaskDefaults(taskData,currentTaskIdx);

% taskList must also be updated
dlgdata.taskInfo.dataStrings(currentTaskIdx) = {newTaskName};

% append task to list of new tasks
dlgdata.taskInfo.newTask = unique([dlgdata.taskInfo.newTask, newTaskName]);
bModified = 1;

dlgdata.taskData = taskData;


%--------------------------------------------------------------------------
% FcnDeleteTask remove current task
%
% INPUT ARGUMENTS
%   dlgdata     dialog data
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%--------------------------------------------------------------------------
function dlgdata = FcnDeleteTask(dlgdata)

taskData = dlgdata.taskData;
taskInfo = dlgdata.taskInfo;

% get relevant indices
taskList = taskInfo.dataStrings;
delTask  = dlgdata.data.task;
delTaskIdx = find(strcmp(delTask,taskList));

% add tasks to list of deleted tasks
taskInfo.deletedTask = unique([taskInfo.deletedTask,delTask]);

% remove task from list of added tasks
idx = find(strcmp(delTask,taskInfo.newTask));
if ~isempty(idx),
    taskInfo.newTask(idx) = [];
end

% purge property struct
taskInfo.dataStrings(delTaskIdx) = [];
taskData(delTaskIdx) = [];

% set updated value at uiControls
if isempty(taskInfo.dataStrings),
    % no more task available
    dlgdata.data.task = ' ';
    taskInfo.dataStrings = {' '};
    taskData = FcnSetTaskDefaults([],1);
    taskData(1).bValid = 0;
else
    % select the first element from taskList
    dlgdata.data.task = taskInfo.dataStrings{1};
end

dlgdata.taskData = taskData;
dlgdata.taskInfo = taskInfo;


%-------------------------------------------------------
% FcnGetTaskDataFromDD
%   gets all necessary data of tasks from DD and puts it into an additional field 'taskData' of dlgdata
%
% INPUT ARGUMENTS
%   dlgdata      dialog data structure
%
% OUTPUT ARGUMENTS
%   dlgdata      modified dialog data structure
%-------------------------------------------------------
function dlgdata = FcnGetTaskDataFromDD(dlgdata)

% initialize lists holding added and deleted tasks
taskInfo.newTask     = {};
taskInfo.deletedTask = {};
taskInfo.editedTask  = {};

currentTask = dlgdata.data.task;
ddTaskPath  = '/Pool/RTOS/Tasks';
% retrieve task list from DataDictionary
[taskList, errCode] = dsdd('GetChildrenNames',ddTaskPath);
if dsdd_check_msg(errCode),
    return
end
if isempty(taskList),
    % no tasks available
    taskList = {currentTask};
    taskIdx = 1;
    taskData = FcnSetTaskDefaults([],taskIdx);
    % mark task as not valid
    taskData.bValid = 0;
else
    % begin import task data
    taskData(1:length(taskList)) = FcnSetTaskDefaults([],1);
    for m = 1:length(taskList),
        taskName = taskList{m};
        taskObject = [ddTaskPath,'/',taskName];
        [bExist,hTaskObject] = dsdd('exist',taskObject);
        % description
        [taskData(m).description,errCode] = dsdd('GetDescription',hTaskObject);
        if dsdd_check_msg(errCode),
            taskData(m).description = '';
        end
        % module
        taskData(m).module = '';
        hModuleObject = dsdd('GetModuleRefTarget', hTaskObject);
        if ~isempty(hModuleObject)
            [taskData(m).module,errCode] = dsdd('GetAttribute', hModuleObject, 'path');
            taskData(m).module = strrep(taskData(m).module, '//DD0/Pool/Modules/', '');
        else
            taskData(m).module = dsdd('GetModuleRef', hTaskObject);
        end
        if dsdd_check_msg(errCode),
            taskData(m).module = '';
        end
        % functionclass
        taskData(m).functionclass = dsdd('GetFunctionClassRef',hTaskObject);
        if isempty(taskData(m).functionclass),
            taskData(m).functionclass = 'default';
        end
        % priority
        [taskData(m).priority,errCode] = dsdd('GetPriority',hTaskObject);
        if dsdd_check_msg(errCode),
            taskData(m).priority = '';
        elseif isempty(taskData(m).priority)
            taskData(m).priority = 'auto';
        else
            taskData(m).priority = num2str(taskData(m).priority);
        end
        % preemptive property is boolean
        [taskData(m).preemptive,errCode] = dsdd('GetPreemptive',hTaskObject);
        if dsdd_check_msg(errCode),
            taskData(m).preemptive = 0;
        end
        % events
        eventList = FcnGetEventList(hTaskObject);
        taskData(m).eventStrings = eventList;
        % use activating alarm
        event = dlgdata.data.event;
        if strcmp(event,'none')
            bExist = 1;
        else
            [bExist,hEvent] = dsdd('Exist',event, ...
                'Parent','/Pool/RTOS/Events');
        end
        if ~bExist,
            ds_error_msg( ['The previously set event ''',event,''' for task ', ...
                '''',taskName,''' couldn''t ', ...
                'be found in your current Data Dictionary. It ', ...
                'is strongly recommended that you create the ', ...
                'missing event object or select another existing ', ...
                'event.'], ...
                'MessageType',     'Warning');
            % fallback: event = 'none'
            event = 'none';
        end
        taskData(m).event = event;
        if strcmp(event,'none'),
            hDDObject = hTaskObject;
        else
            hDDObject = hEvent;
        end
        [taskData(m).useactivatingalarm,errCode] = dsdd('GetUseActivatingAlarm',hDDObject);
        if dsdd_check_msg(errCode),
            taskData(m).useactivatingalarm = 'DEFAULT';
        end
        % alarms
        alarmList = FcnGetAlarmList(taskName,taskData(m).event);
        taskData(m).alarm = dsdd('GetActivatingAlarmRef',hDDObject);
        alarmIdx  = find(strcmp(taskData(m).alarm,alarmList), 1);
        if isempty(alarmIdx),
            alarmList = [{taskData(m).alarm},alarmList];                            %#ok
        end
        taskData(m).alarmStrings = alarmList;
        % activation
        [taskData(m).activations,errCode] = dsdd('GetActivation',hTaskObject);
        if dsdd_check_msg(errCode),
            taskData(m).activations = 1;
        end
        % autostart
        [taskData(m).autostart,errCode] = dsdd('GetAutoStart',hTaskObject);
        if dsdd_check_msg(errCode),
            taskData(m).autostart = 0;
        end
        dlgdata.data.event = event;
    end
end

taskInfo.dataStrings  = taskList;
dlgdata.taskInfo = taskInfo;
dlgdata.taskData = taskData;


%-------------------------------------------------------
% FcnSetTaskDefaults
%   creates default data structure for tasks
%
% INPUT ARGUMENTS
%   taskData        current task data struct
%   idx             index of current task
%
% OUTPUT ARGUMENTS
%   taskData       initialized task data structure
%-------------------------------------------------------
function taskData = FcnSetTaskDefaults(taskData,idx)

taskData(idx).description   = '';
taskData(idx).module      = '';
taskData(idx).functionclass = 'default';
taskData(idx).priority      = '';
taskData(idx).preemptive    = 0;
taskData(idx).eventStrings  = {};
taskData(idx).event         = 'none';
taskData(idx).useactivatingalarm = 'DEFAULT';
taskData(idx).alarmStrings  = {};
taskData(idx).alarm         = ' ';
taskData(idx).activations   = 1;
taskData(idx).autostart     = 0;
taskData(idx).bValid        = 1;


%--------------------------------------------------------------------------
% FcnGetAlarmList compile a list of relevant alarms
%
% INPUT ARGUMENTS
%   taskName      name of task
%   eventName     name of event
%
% OUTPUT ARGUMENTS
%   alarmList     list of alarms
%--------------------------------------------------------------------------
function alarmList = FcnGetAlarmList(taskName,eventName)

% determine search criteria
bSearchTaskRef = strcmp(eventName,'none');

% iterate over all alarms
alarmList = {};
hAlarm = dsdd('GetChildren','/Pool/RTOS/Alarms');
for n = 1:length(hAlarm),
    [alarmName,errCode] = dsdd('GetAttribute',hAlarm(n),'Name');
    if dsdd_check_msg(errCode),
        % continue with next alarm
        continue;
    end
    % alarm gets a list member if automatic actions assigment is true
    if dsdd('GetAutomaticActionAssignment',hAlarm(n)),
        alarmList = [alarmList,{alarmName}];        %#ok
        continue;
    end
    % check if manual action assigment matches task or event
    [hAction,errCode] = dsdd('GetAction',hAlarm(n));
    if dsdd_check_msg(errCode)
        continue
    end
    actionKind = dsdd('GetActionKind',hAction);
    if bSearchTaskRef,
        if ~strcmp(actionKind,'ACTIVATETASK'),
            continue
        end
        h = dsdd('GetTaskRef',hAction);
        if isequal(h,taskName),
            alarmList = [alarmList,{alarmName}];        %#ok
        end
    else
        if ~strcmp(actionKind,'SETEVENT'),
            continue
        end
        h = dsdd('GetEventRef',hAction);
        if isequal(h,eventName),
            alarmList = [alarmList,{alarmName}];        %#ok
        end
    end
end

if isempty(alarmList),
    alarmList = {' '};
end


%--------------------------------------------------------------------------
% FcnManageEvent manages event settings
%
% INPUT ARGUMENTS
%   dlgdata             dialog data
%   currentTaskIdx      index of current task
%
% OUTPUT ARGUMENTS
%   dlgdata             modified dialog data
%--------------------------------------------------------------------------
function dlgdata = FcnManageEvent(dlgdata)

if ~isempty(dlgdata.taskInfo.newTask) ...
        || ~isempty(dlgdata.taskInfo.deletedTask) ...
        || ~isempty(dlgdata.taskInfo.editedTask)
    % force applying
    btn = ds_msgbox( ...
        'Message',     ['Before you can continue with managing events it''s necessary ', ...
        'that you apply your task settings.'], ...
        'Title',       'Please apply your task settings', ...
        'Button',      {'Apply now','Cancel'}, ...
        'Default',     'Cancel', ...
        'Mode',        'modal', ...
        'Style',       'question' ...
        );

    % return by user request
    if strcmp(btn,'Cancel'),
        return
    end

    % apply the current settings and retrieve the changed userData
    dlgdata = FcnApply(dlgdata);
end

% invoke the subdialog for managing events
taskName = dlgdata.data.task;
[bExist,hTask] = dsdd('Exist',['/Pool/RTOS/Tasks/',taskName]);
subDlgUserData = tl_manage_events_dlg('Create',taskName);

% return if subdialog wasn't created
if ~isstruct(subDlgUserData),
    return
end

% wait until the subdialog is closed
set(subDlgUserData.hDlg,'WindowStyle','modal');
uiwait(subDlgUserData.hDlg);

% update the event selection popup
taskList          = dlgdata.taskInfo.dataStrings;
currentTaskIdx    = find(strcmp(taskName,taskList));

eventList = FcnGetEventList(hTask);
eventName = dlgdata.taskData(currentTaskIdx).event;
eventIdx  = find(strcmp(eventName,eventList));
if isempty(eventIdx),
    eventIdx = 1;
end
dlgdata.taskData(currentTaskIdx).eventStrings = eventList;
dlgdata.taskData(currentTaskIdx).event = eventList{eventIdx};
dlgdata.data.event = eventList{eventIdx};


%--------------------------------------------------------------------------
% FcnManageAlarms manages alarms settings
%
% INPUT ARGUMENTS
%   dlgdata             dialog data
%   currentTaskIdx      index of current task
%
% OUTPUT ARGUMENTS
%   dlgdata             modified dialog data
%--------------------------------------------------------------------------
function dlgdata = FcnManageAlarms(dlgdata,currentTaskIdx)

if ~isempty(dlgdata.taskInfo.newTask) ...
        || ~isempty(dlgdata.taskInfo.deletedTask) ...
        || ~isempty(dlgdata.taskInfo.editedTask)
    % force applying
    btn = ds_msgbox( ...
        'Message',     ['Before you can continue with managing alarms it''s necessary ', ...
        'that you apply your task settings.'], ...
        'Title',       'Please apply your task settings', ...
        'Button',      {'Apply now','Cancel'}, ...
        'Default',     'Cancel', ...
        'Mode',        'modal', ...
        'Style',       'question' ...
        );

    % return by user request
    if strcmp(btn,'Cancel'),
        return
    end

    % apply the current settings and retrieve the changed userData
    dlgdata = FcnApply(dlgdata);
end

% get handle of task object
if ~dsdd('Exist',['/Pool/RTOS/Tasks/',dlgdata.data.task]),
    ds_error_msg('Assertion failed: Task doesn''t exist');
end

% invoke the subdialog for managing alarms
alarmName = dlgdata.taskData(currentTaskIdx).alarm;
tl_manage_alarms_dlg('Create',alarmName);

% wait until the subdialog is closed
subDlgUserData = ds_generic_dlg('GetUserData(#Fig_tl_manage_alarms_dlg)');
set(subDlgUserData.hDlg,'WindowStyle','modal');
uiwait(subDlgUserData.hDlg);


%--------------------------------------------------------------------------
% FcnVendorSettings manage vendor settings
%
% INPUT ARGUMENTS
%   dlgdata     dialog data
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%--------------------------------------------------------------------------
function dlgdata = FcnVendorSettings(dlgdata)

% determine current task
task = dlgdata.data.task;

% invoke subdialog for vendor settings
subDlgdata = tl_vendor_properties_dlg('Create',dlgdata.model,task);
if isempty(subDlgdata),
    return
end

% wait for return from modal dialog
set(subDlgdata.hDlg,'WindowStyle','modal');
uiwait(subDlgdata.hDlg);
